/* Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>

#include "cmsis_os2.h"

#include "host/ble_hs.h"
#include "host/util/util.h"
#include "iotsdk_nimble.h"
#include "nimble/nimble_port.h"
#include "services/gap/ble_svc_gap.h"
#include "services/gatt/ble_svc_gatt.h"
#include "syscfg/syscfg.h"

extern void ble_store_ram_init(void);

#ifndef BLE_NIMBLE_EVENT_THREAD_STACK_SIZE
#define BLE_NIMBLE_EVENT_THREAD_STACK_SIZE 2048
#endif

static void host_stack_task()
{
    nimble_port_run();
    // never returns
}

void ble_init(void)
{
    ble_transport_ll_init();

    nimble_port_init();

    ble_store_ram_init();

    ble_svc_gap_init();
    ble_svc_gatt_init();
}

void ble_start(void)
{
    osThreadAttr_t thread_attr = {.stack_size = BLE_NIMBLE_EVENT_THREAD_STACK_SIZE};
    osThreadId_t host_thread_id = osThreadNew(host_stack_task, NULL, &thread_attr);
    if (!host_thread_id) {
        BLE_HS_LOG_ERROR("Critical error, unable to create thread for the BLE host stack.");
        abort();
    }

    // the procedure is done by the HS task, we wait until it's done
    while (!ble_hs_synced() || !ble_hs_is_enabled()) {
        osDelay(osKernelGetTickFreq() / 100);
    }

    ble_hs_util_ensure_addr(1);
}
